package com.sh.business.controller.portal;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.lock.annotation.Lock4j;
import com.sh.business.domain.FinancingBo;
import com.sh.business.domain.bo.*;
import com.sh.business.domain.form.*;
import com.sh.business.domain.vo.*;
import com.sh.business.service.*;
import com.sh.business.service.facade.UserServiceFacade;
import com.sh.common.core.domain.R;
import com.sh.common.core.validate.AddGroup;
import com.sh.common.encrypt.annotation.ApiEncrypt;
import com.sh.common.idempotent.annotation.RepeatSubmit;
import com.sh.common.log.annotation.Log;
import com.sh.common.log.enums.BusinessType;
import com.sh.common.mybatis.core.page.PageQuery;
import com.sh.common.mybatis.core.page.TableDataInfo;
import com.sh.common.ratelimiter.annotation.RateLimiter;
import com.sh.common.ratelimiter.enums.LimitType;
import com.sh.common.satoken.utils.LoginHelper;
import com.sh.common.web.core.BaseController;
import com.sh.system.domain.vo.SysOssUploadVo;
import com.sh.system.domain.vo.SysOssVo;
import com.sh.system.service.ISysOssService;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.web3j.crypto.WalletUtils;

import java.util.List;

import static com.sh.common.core.domain.R.SUCCESS_MSG;

/**
 * 前端接口-首页
 *
 * @author ruoyi
 * @date 2024-10-09
 */
@SaCheckLogin
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/portal/user")
public class PortalController extends BaseController {

    private final IUserService userService;
    private final IBannerService iBannerService;
    private final INoticeService iNoticeService;
    private final IMiningService iMiningService;
    private final IDocumentService iDocumentService;
    private final ISysOssService ossService;
    private final IUserInvestService iUserInvestService;
    private final IUserFundDetailService bmsUserFundDetailService;
    private final IUserWithdrawalService iUserWithdrawalService;
    private final IFeedbackService feedbackService;
    private final IPriceTrendsService priceTrendsService;
    private final IUserRepurchaseService iUserRepurchaseService;


    /**
     * 登录
     */
    //@ApiEncrypt(response = true)
    @SaIgnore
    @PostMapping("/login")
    public R<String> login(@Validated @RequestBody UserLoginBo bo) {
        return R.ok(SUCCESS_MSG, userService.login(bo));
    }

    /**
     * 获取用户信息
     *
     */
    @GetMapping("/getUserInfo")
    public R<UserDataVo> getUserInfo() {
        return R.ok(userService.getUserInfo(LoginHelper.getUserId()));
    }

    /**
     * 查询banner
     */
    @SaIgnore
    @GetMapping("/queryBannerByType")
    public R<List<BannerVo>> queryBannerByType(BannerBo bo) {
        return R.ok(iBannerService.queryBannerByType(bo));
    }

    /**
     * 查询公告列表
     */
    @SaIgnore
    @GetMapping("/queryNoticeList")
    public TableDataInfo<NoticeVo> list(NoticeBo bo, PageQuery pageQuery) {
        return iNoticeService.queryPortalPageList(bo, pageQuery);
    }

    /**
     * 查询矿机列表
     */
    @SaIgnore
    @GetMapping("/queryMiningList")
    public R<List<MiningVo>> queryMiningList(MiningBo bo) {
        return R.ok(iMiningService.queryList(bo));
    }

    /**
     * 查询文案
     */
    @SaIgnore
    @GetMapping("/queryDocumentByType")
    public R<DocumentVo> queryDocumentByType(DocumentBo bo) {
        return R.ok(iDocumentService.queryDocumentByType(bo));
    }

    /**
     * 保存签名
     *
     * @param file 文件
     */
    @Log(title = "保存签名", businessType = BusinessType.INSERT)
    @PostMapping(value = "/saveSignature", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Void> saveSignature(@RequestPart("file") MultipartFile file) {
        if (ObjectUtil.isNull(file)) {
            return R.fail("The uploaded file cannot be empty");
        }
        SysOssVo oss = ossService.uploadPortal(file);
        return toAjax(userService.saveSignature(oss.getUrl()));
    }

    /**
     * 充值复购u
     */
    @Log(title = "充值复购u", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/rechargeRepurchaseUsdt")
    public R<Void> rechargeRepurchaseUsdt(@Validated(AddGroup.class) @RequestBody UserRepurchaseBo bo) {
        return toAjax(iUserRepurchaseService.insertByBo(bo));
    }

    /**
     * 购买-废弃
     */
    @Log(title = "购买", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody UserInvestBo bo) {
        return toAjax(iUserInvestService.insertByBo(bo));
    }

    /**
     * 购买-新版
     */
    @Log(title = "购买/充值", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("purchase")
    @Lock4j
    public R<Void> purchase(@Validated @RequestBody PurchaseBo bo) {
        return toAjax(iUserInvestService.purchase(bo));
    }

    /**
     * 组合复购
     */
    @Log(title = "组合复购", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("repurchase")
    @Lock4j
    public R<Void> repurchase(@Validated @RequestBody RepurchaseBo bo) {
        return toAjax(iUserInvestService.repurchase(bo));
    }

    /**
     * 完善aleo地址
     */
    @Log(title = "完善aleo地址", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/completeAddress")
    public R<Void> completeAddress(@Validated @RequestBody AleoAddressBo bo) {
        return toAjax(userService.completeAddress(bo));
    }

    /**
     * 查询算力
     */
    @GetMapping("/queryComputility")
    public R<UserComputilityDataVo> queryComputility() {
        return R.ok(userService.queryComputility());
    }

    /**
     * 每日新增
     *
     */
    @SaCheckLogin
    @GetMapping("/queryTodayMyTeam")
    public R<MyTeamVo> queryTodayMyTeam() {
        return R.ok(userService.queryTodayMyTeam());
    }

    /**
     * 团队统计
     *
     */
    @SaCheckLogin
    @GetMapping("/queryMyTeam")
    public R<MyTeamVo> queryMyTeam() {
        return R.ok(userService.queryMyTeam());
    }

    /**
     * 直推列表
     */
    @SaCheckLogin
    @GetMapping("/queryDirectPushPageList")
    public TableDataInfo<DirectPushUserVo> queryDirectPushPageList(PageQuery pageQuery) {
        return userService.queryDirectPushPageList(pageQuery);
    }

    /**
     * 查询用户资产明细列表
     */
    @GetMapping("/list")
    public TableDataInfo<UserFundDetailVo> list(UserFundDetailBo bo, PageQuery pageQuery) {
        return bmsUserFundDetailService.queryPortalPageList(bo, pageQuery);
    }

    /**
     * 提现
     */
    @Log(title = "提现", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/withdrawal")
    @Lock4j
    public R<Void> withdrawal(@Validated(AddGroup.class) @RequestBody UserWithdrawalBo bo) {
        return toAjax(iUserWithdrawalService.insertByBo(bo));
    }

    /**
     * 设置密码
     */
    @Log(title = "设置密码", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/password")
    public R<Void> password(@Validated @RequestBody PasswordBo bo) {
        return toAjax(userService.setPassword(bo));
    }

    /**
     * 修改密码
     */
    @Log(title = "修改密码", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/modifyPassword")
    public R<Void> modifyPassword(@Validated @RequestBody ModifyPasswordBo bo) {
        return toAjax(userService.modifyPassword(bo));
    }

    /**
     * 获取公告详细信息
     *
     * @param noticeId 主键
     */
    @SaIgnore
    @GetMapping("/notice/{noticeId}")
    public R<NoticeVo> getInfo(@NotNull(message = "noticeId can't be empty")
                               @PathVariable Long noticeId) {
        return R.ok(iNoticeService.queryById(noticeId));
    }

    /**
     * 提交反馈
     */
    @Log(title = "用户反馈", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/feedback")
    public R<Void> add(@Validated(AddGroup.class) @RequestBody FeedbackBo bo) {
        return toAjax(feedbackService.insertByBo(bo));
    }

    /**
     * 我的反馈列表
     */
    @GetMapping("/queryMyFeedback")
    public TableDataInfo<FeedbackVo> list(FeedbackBo bo, PageQuery pageQuery) {
        return feedbackService.queryPortalPageList(bo, pageQuery);
    }

    /**
     * 上传文件
     */
    @Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<SysOssVo> upload(@RequestPart("file") MultipartFile file) {
        if (ObjectUtil.isNull(file)) {
            return R.fail("The uploaded file cannot be empty");
        }
        SysOssVo oss = ossService.uploadPortal(file);
        return R.ok(oss);
    }

    /**
     * 转账
     */
    @RateLimiter(count = 10, time = 3600, limitType = LimitType.IP)
    @Log(title = "转账", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/transfer")
    @Lock4j
    public R<Void> transfer(@Validated @RequestBody TransferBo bo) {
        userService.transfer(bo);
        return R.ok("success");
    }

    /**
     * 兑换
     */
    @Log(title = "兑换", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/convert")
    @Lock4j
    public R<Void> convert(@Validated @RequestBody AssetConvertBo bo) {
        return toAjax(userService.convertAsset(bo));
    }

    /**
     * 转入理财
     */
    @Log(title = "转入理财", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/financing")
    @Lock4j
    public R<Void> financing(@Validated @RequestBody FinancingBo bo) {
        return toAjax(userService.financing(bo));
    }

    /**
     * 理财转出
     */
    @Log(title = "理财转出", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/extract")
    @Lock4j
    public R<Void> extract() {
        return toAjax(userService.extract());
    }

    /**
     * 查询价格趋势列表
     */
    @SaIgnore
    @GetMapping("/priceTrendsList")
    public TableDataInfo<PriceTrendsVo> priceTrendsList(PriceTrendsBo bo, PageQuery pageQuery) {
        return priceTrendsService.queryPortalPageList(bo, pageQuery);
    }

    /**
     * 查询节点列表 - 滚动
     */
    @SaIgnore
    @GetMapping("/queryNodePageList")
    public TableDataInfo<UserNodeVo> queryNodePageList(PageQuery pageQuery) {
        return userService.queryNodePageList(pageQuery);
    }


}
